package verifier.util;

import jdd.bdd.BDDIO;
import network.Port;
import verifier.Ports.PersistentPorts;
import verifier.Ports.Ports;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

public class PPM {
    private final HashMap<Ports, Integer> portsToPredicate;

    public PPM(HashMap<Ports, Integer> portsToPredicate) {
        this.portsToPredicate = portsToPredicate;
    }

    public HashMap<Port, HashSet<Integer>> getPortToPreds() {
        HashMap<Port, HashSet<Integer>> portToPreds = new HashMap<>();
        for (Map.Entry<Ports, Integer> entry : this.portsToPredicate.entrySet()) {
            Ports ports = entry.getKey();
            int pred = entry.getValue();
            for (Port port : ports.getAll()) {
                portToPreds.computeIfAbsent(port, k -> new HashSet<>());
                portToPreds.get(port).add(pred);
            }
        }
        return portToPreds;
    }

//    public HashMap<Port, HashSet<byte[]>> getPortToPredsBytes() {
//        if (this.portToPredsBytes != null) {
//            return portToPredsBytes;
//        }
//        this.portToPredsBytes = new HashMap<>();
//        for (Map.Entry<Ports, Integer> entry : this.portsToPredicate.entrySet()) {
//            Ports ports = entry.getKey();
//            int pred = entry.getValue();
//            for (Port port : ports.getAll()) {
//                this.portToPredsBytes.computeIfAbsent(port, k -> new HashSet<>());
//                ByteArrayOutputStream bos = new ByteArrayOutputStream();
//                try {
//                    BDDIO.save(this.bddEngine.getBdd(), pred, bos);
//                    this.portToPredsBytes.get(port).add(bos.toByteArray());
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//        }
//        return this.portToPredsBytes;
//    }

//    public HashMap<Port, byte[]> getPortToUnionPredsBytes() {
//        if (this.portToUnionPredsBytes != null) {
//            return portToUnionPredsBytes;
//        }
//        this.portToUnionPredsBytes = new HashMap<>();
//        for (Map.Entry<Port, HashSet<Integer>> entry : this.getPortToPreds().entrySet()) {
//            int union = entry.getValue().stream().reduce(0, this.bddEngine::or);
//            ByteArrayOutputStream bos = new ByteArrayOutputStream();
//            try {
//                BDDIO.save(this.bddEngine.getBdd(), union, bos);
//                this.portToUnionPredsBytes.computeIfAbsent(entry.getKey(), k -> bos.toByteArray());
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//        }
//        return this.portToUnionPredsBytes;
//    }
//
//    public HashMap<Ports, byte[]> getPortsToPredsBytes() {
//        if (this.portsToPredsBytes == null) {
//            this.portsToPredsBytes = new HashMap<>();
//            for (Map.Entry<Ports, Integer> entry : this.portsToPredicate.entrySet()) {
//                Ports ports = entry.getKey();
//                int pred = entry.getValue();
//                try {
//                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
//                    BDDIO.save(this.bddEngine.getBdd(), pred, bos);
//                    this.portsToPredsBytes.put(ports, bos.toByteArray());
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//        }
//        return this.portsToPredsBytes;
//    }

}
